// 转换字符串，undefined,null等转化为""
export function praseStrEmpty(str) {
  if (!str || str == "undefined" || str == "null") {
    return "";
  }
  return str;
}

// sso单点登录路径解析
export function getParamsKey(name) {
  let reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
  let r = window.location.search.substring(1).match(reg);
  if (r !== null) {
    return decodeURI(r[2]);
  }
}
/**
 * 前端公用方法
 */
import FileSaver from "file-saver";
import * as XLSX from "xlsx";
import XLSXStyle from "xlsx-js-style";
const commontFn = {
  /***
   * 文件上传
   */
  upload(single) {
    return new Promise((resolve, reject) => {
      const input = document.createElement("input");
      input.type = "file";
      let elm = document.createElement("input");
      elm.setAttribute("type", "file");
      if (!single) {
        elm.setAttribute("multiple", true);
      }
      elm.style.display = "none";
      elm.addEventListener("change", async (e) => {
        const files = e.target.files || e.dataTransfer.files;
        document.body.removeChild(elm);
        elm = null;
        resolve(files);
      });
      document.body.appendChild(elm);
      elm.click();
    });
  },
  // 直接返回blob对象时导出解析可用改方法
  fileDownloadExport(response, fileName) {
    const url = window.URL.createObjectURL(response);
    const dom = document.createElement("a"); // 设置一个隐藏的 a 标签，href 为输出流，设置 download
    dom.style.display = "none";
    dom.href = url;
    dom.setAttribute("download", fileName); // 指示浏览器下载 url,而不是导航到它；因此将提示用户将其保存为本地文件
    document.body.appendChild(dom);
    dom.click();
    document.body.removeChild(dom); // 下载完成移除元素
    window.URL.revokeObjectURL(url); // 释放掉 blob 对象
  },
  /**
   * 本地文件
   * @param {*} path
   * @param {*} fileName
   */
  fileDownloadLocal(path, fileName) {
    const dom = document.createElement("a"); // 设置一个隐藏的 a 标签，href 为输出流，设置 download
    dom.style.display = "none";
    dom.href = path;
    dom.setAttribute("download", fileName); // 指示浏览器下载 url,而不是导航到它；因此将提示用户将其保存为本地文件
    document.body.appendChild(dom);
    dom.click();
    document.body.removeChild(dom); // 下载完成移除元素
  },

  /***
   * 文件下载
   */
  fileDownload(response, fileName) {
    const blob = new Blob([response]); // 创建一个类文件对象：Blob 对象表示一个不可变的、原始数据的类文件对象
    // URL.createObjectURL(object) 表示生成一个 File 对象或 Blob 对象
    const url = window.URL.createObjectURL(blob);
    const dom = document.createElement("a"); // 设置一个隐藏的 a 标签，href 为输出流，设置 download
    dom.style.display = "none";
    dom.href = url;
    dom.setAttribute("download", fileName); // 指示浏览器下载 url,而不是导航到它；因此将提示用户将其保存为本地文件
    document.body.appendChild(dom);
    dom.click();
    document.body.removeChild(dom); // 下载完成移除元素
    window.URL.revokeObjectURL(url); // 释放掉 blob 对象
  },
  addMonths(v, n) {
    v = new Date(v);
    if (v) {
      var t = new Date(
        v.getFullYear(),
        v.getMonth(),
        v.getDate(),
        v.getHours(),
        v.getMinutes(),
        v.getSeconds(),
        v.getMilliseconds()
      );
      t.setMonth(v.getMonth() + n);
      if (t.getDate() !== v.getDate()) {
        t.setDate(0);
      }
      return t;
    }
  },

  /**
   * 时间整理方法
   * @param {any} time :需要整理的时间
   * @param {string} fmt :需要整理成的时间格式，默认yyyy-MM-dd hh:mm:ss
   * @returns {string}fmt:整理后页面显示格式
   */
  parse(time, fmt = "yyyy-MM-dd hh:mm:ss") {
    const newTime = new Date(time);
    let we = newTime.getDay(); // 星期
    let qut = Math.floor((newTime.getMonth() + 3) / 3).toString(); // 季度
    var o = {
      "M+": newTime.getMonth() + 1, //月份
      "d+": newTime.getDate(), //日
      "h+": newTime.getHours(), //小时
      "m+": newTime.getMinutes(), //分
      "s+": newTime.getSeconds(), //秒
      "q+": qut, //季度
    };
    // 年
    if (/(y+)/.test(fmt)) {
      // 它显示了全局 RegExp 对象中的匹配项和子匹配项。
      // console.log("RegExp.$1", RegExp.$1);   //yyyy
      fmt = fmt.replace(
        RegExp.$1,
        (newTime.getFullYear() + "").substr(4 - RegExp.$1.length)
      );
      // console.log(
      //   "sustr的结果",
      //   (newTime.getFullYear() + "").substr(4 - RegExp.$1.length)    //2024
      // );
    }
    const week = {
      // 中文数字 (星期)
      0: "日",
      1: "一",
      2: "二",
      3: "三",
      4: "四",
      5: "五",
      6: "六",
    };
    const quarter = {
      // 中文数字（季度）
      1: "一",
      2: "二",
      3: "三",
      4: "四",
    };
    // 星期
    if (/(W+)/.test(fmt)) {
      fmt = fmt.replace(
        RegExp.$1,
        RegExp.$1.length > 1
          ? RegExp.$1.length > 2
            ? "星期" + week[we]
            : "周" + week[we]
          : week[we]
      );
    }
    // 季度
    if (/(Q+)/.test(fmt)) {
      // 输入一个Q，只输出一个中文数字，输入4个Q，则拼接上字符串
      fmt = fmt.replace(
        RegExp.$1,
        RegExp.$1.length == 4 ? "第" + quarter[qut] + "季度" : quarter[qut]
      );
    }
    for (var k in o) {
      if (new RegExp("(" + k + ")").test(fmt)) {
        //拼0
        fmt = fmt.replace(
          RegExp.$1,
          RegExp.$1.length === 1
            ? o[k]
            : ("00" + o[k]).substr(("" + o[k]).length)
        );
      }
    }
    return fmt;
  },
  /**
   *根据周的起始日期获取当前周是第几周
   * @param {any} time :当前周的起始日期 2024-06-24 00:00:00
   */
  getWeekNumber(date) {
    var now = new Date(date);
    // new Date多个参数分别代表年、月、日、小时、分钟、秒和毫秒。
    var startOfYear = new Date(now.getFullYear(), 0, 0);
    var diff = now - startOfYear; //2个时间对象相减=毫秒数
    var oneWeekInMilliseconds = 1000 * 60 * 60 * 24 * 7;
    // 向上取整，即只要到本周的第一天就为一周
    var weekNumber = Math.ceil(diff / oneWeekInMilliseconds);
    return weekNumber;
  },

  //获取近N天
  getRecentDay(day, range = "min", time = new Date()) {
    var today = time;
    let tHours = "00";
    let tMinutes = "00";
    if (typeof time === "string") {
      if (range === "hour") {
        time += ":00";
      }
      today = new Date(time);
    }
    switch (range) {
      case "min":
        today.setHours(today.getHours() + day / 4);
        break;
      case "hour":
        today.setHours(today.getHours() + day);
        break;
      case "date":
        today.setDate(today.getDate() + day);
        break;
      case "month":
        today.setMonth(today.getMonth() + day);
        break;
      case "year":
        today.setFullYear(today.getFullYear() + day);
        break;
      default:
        break;
    }
    var tYear = today.getFullYear();
    var tMonth = today.getMonth();
    var tDate = today.getDate();
    tMonth = (tMonth + 1).toString().padStart(2, "0");
    tDate = tDate.toString().padStart(2, "0");
    if (typeof time === "string") {
      tHours = today.getHours();
      tMinutes = today.getMinutes();
      tHours = tHours.toString().padStart(2, "0");
      tMinutes = tMinutes.toString().padStart(2, "0");
    }
    let result =
      tYear + "-" + tMonth + "-" + tDate + " " + tHours + ":" + tMinutes;
    switch (range) {
      case "hour":
        result = tYear + "-" + tMonth + "-" + tDate + " " + tHours;
        break;
      case "date":
        result = tYear + "-" + tMonth + "-" + tDate;
        break;
      case "month":
        result = tYear + "-" + tMonth;
        break;
      case "year":
        result = "" + tYear;
        break;
      default:
        break;
    }
    return result;
  },
  //关闭弹窗修改modal层位置
  closeDialogModal() {
    let dialogElArr = document.getElementsByClassName("el-dialog__wrapper");
    let dialogEl = "";
    if (dialogElArr.length > 1) {
      dialogEl = dialogElArr[dialogElArr.length - 2];
    } else if (dialogElArr.length === 1) {
      dialogEl = dialogElArr[0];
    }
    let modalEl = document.getElementsByClassName("v-modal")[0];
    if (dialogEl && modalEl) {
      dialogEl.parentElement.appendChild(modalEl);
    } else if (dialogEl === "" && modalEl) {
      modalEl.remove();
    }
  },
  // //文档流导出
  // exportFile(data, name, type = ".xlsx") {
  //   let blob = new Blob([data], { type: "application/vnd.ms-excel" }); //type是文件类，详情可以参阅blob文件类型
  //   let objectUrl = URL.createObjectURL(blob); //生成下载链接
  //   let link = document.createElement("a");
  //   link.href = objectUrl;
  //   link.download = name + type;
  //   document.body.appendChild(link);
  //   link.click();
  //   document.body.removeChild(link);
  // },
  // //PDF流导出
  // exportPdfFile(data, name, type = ".pdf") {
  //   let blob = new Blob([data], { type: "application/pdf" }); //type是文件类，详情可以参阅blob文件类型
  //   let objectUrl = URL.createObjectURL(data); //生成下载链接
  //   let link = document.createElement("a");
  //   link.href = objectUrl;
  //   link.download = name + type;
  //   document.body.appendChild(link);
  //   link.click();
  //   document.body.removeChild(link);
  // },

  // 导出压缩包
  // exportZip(data, name, type = ".zip") {
  //   let blob = new Blob([data], { type: "application/zip" }); //type是文件类，详情可以参阅blob文件类型
  //   let objectUrl = URL.createObjectURL(blob); //生成下载链接
  //   let link = document.createElement("a");
  //   link.href = objectUrl;
  //   link.download = name + this.parse(new Date(), "yyyyMMddhhmmss") + type;
  //   document.body.appendChild(link);
  //   link.click();
  //   document.body.removeChild(link);
  // },

  // //组件导出
  exportTable(name, fileName, ln) {
    let xlsxParam = { raw: true };
    let tBodyCon = document.querySelector("#" + name);
    let wb;
    wb = XLSX.utils.table_to_book(tBodyCon, xlsxParam);
    let workObj = commontFn.exportXlsxStyleFn(wb, fileName, ln);
    let wopts = {
      type: "binary",
      bookSST: true,
      bookType: "xlsx",
      Props: {
        title: fileName,
        subject: fileName,
        keywords: fileName,
        description: fileName,
      },
    };
    let wbout = XLSXStyle.write(workObj, wopts);
    let blob = new Blob([commontFn.s2ab(wbout)], {
      type: "application/octet-stream",
    });

    try {
      FileSaver.saveAs(blob, fileName + ".xlsx");
    } catch (e) {
      console.log(e, wbout);
    }

    return wbout;
  },
  //导出数据格式转换
  s2ab(s) {
    let buf = new ArrayBuffer(s.length);
    let view = new Uint8Array(buf);
    for (let i = 0; i !== s.length; ++i) {
      view[i] = s.charCodeAt(i) & 0xff;
    }
    return buf;
  },
  //修改导出样式
  exportXlsxStyleFn(wb, fileName, ln) {
    wb.Sheets[fileName] = wb.Sheets[wb.SheetNames[0]];
    delete wb.Sheets[wb.SheetNames[0]];
    wb.SheetNames[0] = fileName;
    let wortkSheet = JSON.parse(JSON.stringify(wb.Sheets[wb.SheetNames[0]]));
    wortkSheet["!cols"] = [];
    for (let i = 0; i < ln; i++) {
      wortkSheet["!cols"][i] = { wch: 20 };
    }
    let arr = [
      "A",
      "B",
      "C",
      "D",
      "E",
      "F",
      "G",
      "H",
      "I",
      "J",
      "K",
      "L",
      "M",
      "N",
      "O",
      "P",
      "Q",
      "R",
      "S",
      "T",
      "U",
      "V",
      "W",
      "X",
      "Y",
      "Z",
    ];
    let letterList = [];
    arr.map((item) => {
      arr.map((it) => {
        letterList.push(item + it);
      });
    });
    letterList = [...arr, ...letterList];
    for (let key in wortkSheet) {
      if (key.indexOf("!") === -1) {
        const word = key.replace(/[0-9]+/g, "");

        // 大于列数的列不绘制边框
        if (letterList.indexOf(word) < ln) {
          wortkSheet[key]["s"] = {
            alignment: {
              vertical: "center",
              horizontal: "center",
            },
            border: {
              color: { auto: 1 },
              top: { style: "thin" },
              bottom: { style: "thin" },
              left: { style: "thin" },
              right: { style: "thin" },
            },
          };
        }
      }
    }
    wortkSheet["!merges"].forEach((item) => {
      const startRowNumber = Math.floor(Number(item.s.c));
      const endRowNumber = Math.floor(Number(item.e.c));
      for (let i = startRowNumber + 1; i <= endRowNumber; i++) {
        // 大于列数的列不绘制边框
        if (i >= ln) {
          continue;
        }
        wortkSheet[letterList[i] + Math.floor(Number(item.e.r) + 1)] = {
          t: "s",
          v: "",
          s: {
            border: {
              top: { style: "thin" },
              left: { style: "thin" },
              bottom: { style: "thin" },
              right: { style: "thin" },
            },
          },
        };
      }
      const startColNumber = Math.floor(Number(item.s.r));
      const endColNumber = Math.floor(Number(item.e.r));
      for (let j = startColNumber + 1; j <= endColNumber; j++) {
        // 大于列数的列不绘制边框
        if (endRowNumber >= ln) {
          continue;
        }
        wortkSheet[letterList[endRowNumber] + (1 + j)] = {
          t: "s",
          v: "",
          s: {
            border: {
              top: { style: "thin" },
              left: { style: "thin" },
              bottom: { style: "thin" },
              right: { style: "thin" },
            },
          },
        };
      }
    });
    wb.Sheets[wb.SheetNames[0]] = wortkSheet;
    return wb;
  },

  // 合并行 组件
  rowSpan(obj, list, columns, id) {
    if (columns.includes(obj.column["property"])) {
      const rowNum = list.filter(
        //id相同的行数
        (it) => it[id] == obj.row[id]
      ).length;
      const currentIndex = list.findIndex(
        (it) => it[id] == obj.row[id] //id相同的第一个索引
      );
      const firstIndex = obj.rowIndex == currentIndex; //判断是否为第一个索引
      const lastIndex = obj.rowIndex == currentIndex + rowNum; //判断是否为最后一个索引
      if (firstIndex) {
        //如果是第一个索引就合并
        return [rowNum, 1];
      } else if (!firstIndex && !lastIndex) {
        //不是第一个。也不是最后一个说明在需要合并的行数内，其余都为0
        return [0, 0];
      }
    }
  },
  // 合并原生表格，渲染表格传list，新增行传list和row
  mergeOriginTable(list, row) {
    const newList = [];
    if (row) {
      list.push(row);
    }
    // 按照 gdbmId 属性分类
    const classifiedObject = list.reduce(function (acc, obj) {
      const key = obj.gdbmId;
      if (!acc[key]) {
        acc[key] = { gdbmId: key, child: [] };
      }
      acc[key].child.push(obj);
      return acc;
    }, {});
    const tempList = Object.values(classifiedObject);
    // console.log(tempList);
    // 计算startRow和endRow值
    const tempList2 = tempList.reduce(function (acc, obj, index) {
      const startRow = index == 0 ? 0 : acc[index - 1].endRow; // 计算 startRow
      const endRow = startRow + obj.child.length; // 计算 endRow
      const rows = obj.child.length;
      obj.startRow = startRow;
      obj.endRow = endRow;
      obj.rows = rows;
      acc.push(obj);
      return acc;
    }, []);
    // console.log(tempList2);
    tempList2.forEach((item, index) => {
      item.child.forEach((citem, cindex) => {
        citem.startRow = item.startRow;
        citem.endRow = item.endRow;
        citem.rows = item.rows;
        newList.push(citem);
      });
    });
    // console.log(newList);
    return newList;
  },
  /**
   * 表格多表头处理
   * @param {Array} list 表格行数据；
   * @returns {Array} columnsList 处理好的表头数据
   */
  columnsHandFn(list) {
    let columnsList = [];
    list.map((item) => {
      let obj = {};
      obj["label"] = item.ColName;
      obj["prop"] = item.DataField;
      if (item.ColName.indexOf("金额") > -1) {
        obj["amount"] = true;
      }
      if (item.Children) {
        obj["Children"] = commontFn.columnsHandFn(item.Children);
      }
      columnsList.push(obj);
    });
    return columnsList;
  },

  /**
   * 表格合并列处理条件值
   * @param {object} row 表格行数据；
   * @param {object} mergeObjItem 一条合并条件。
   * @returns {object} code
   */
  codeFun(row, mergeObjItem) {
    if (typeof mergeObjItem === "string") {
      return row[mergeObjItem];
    }
    let code = "";
    mergeObjItem.map((item) => {
      code += row[item];
    });
    return code;
  },

  /**
   * 表格合并列数据处理
   * @param {Array} data 表格数据列表
   * @param {object} mergeObj 合并条件合集，例如{ age: 'name'}，代表age按照每一行的name相同进行合并。
   * @returns {Array} data
   */
  setMergeSpan(data, mergeObj) {
    if (!data.length) {
      return;
    }
    for (const key in mergeObj) {
      let code = this.codeFun(data[0], mergeObj[key]);
      data[0][`${key}rowspan`] = 1;
      let num = 0;
      for (let i = 1; i < data.length; i++) {
        const newCode = this.codeFun(data[i], mergeObj[key]);
        if (code === newCode) {
          num++;
          data[i][`${key}rowspan`] = 0;
        } else {
          data[i - num - 1][`${key}rowspan`] = num + 1;
          code = newCode;
          num = 0;
        }
        if (i === data.length - 1) {
          if (!num) {
            data[i][`${key}rowspan`] = 1;
          } else {
            data[i - num][`${key}rowspan`] = num + 1;
          }
        }
      }
    }
    return data;
  },

  /**
   * 表格合并列(arco组件)
   * @param {Array} data 表格数据列表；
   * @param {object} mergeObj 合并条件合集，例如{ name: 'name'}，代表name列按照每一行的name相同进行合并。
   * @returns {object} result
   */
  mergeTable(data, mergeObj) {
    const { record, column } = data;
    let result = { rowspan: 1, colspan: 1 };
    for (const key in mergeObj) {
      if ((column["slotName"] || column["dataIndex"]) === key) {
        const num = record[`${key}rowspan`];
        if (num > 1) {
          result = { rowspan: num, colspan: 1 };
        } else if (num < 1) {
          result = { rowspan: 1, colspan: num };
        }
        return result;
      }
    }
  },
  // 组件描述详情的映射   arr包含 name value label  及其他便于区分的字段
  descriptionsDataFn(formItems, formData) {
    let arr = JSON.parse(JSON.stringify(formItems));
    for (let i = 0; i < arr.length; i++) {
      if (arr[i].hide) {
        arr.splice(i, 1);
        i--;
      } else {
        arr[i].value = formData[arr[i].value || arr[i].name];
      }
    }
    return arr;
  },
  // 判断是否为JSON
  isJSON(str) {
    try {
      JSON.parse(str);
    } catch (e) {
      // 转换出错，抛出异常
      return false;
    }
    return true;
  },
  // 文件类型判断
  filterType(type, key) {
    let obj = {
      icon: "",
      text: "",
    };
    switch (type) {
      case 0:
        obj.icon = "icon-wenjianleixing-wenjianjia1";
        obj.text = "文件夹";
        obj.color = "#ffce3d";
        break;
      case 1:
        obj.icon = "icon-wenjianleixing-qita1";
        obj.text = "文件";
        obj.color = "#ccced5";
        break;
      case 2:
        obj.icon = "icon-wenjianleixing-img1";
        obj.text = "图片";
        obj.color = "#ffa65d";
        break;
      case 3:
        obj.icon = "icon-anniugongneng-shipin";
        obj.text = "视频";
        obj.color = "#38abff";
        break;

      default:
        break;
    }
    return obj[key];
  },
  formatICon(fileArr) {
    // 格式化图标
    let arr = [];
    let fileType;
    arr = fileArr.map((it) => {
      if (it.suffix == "txt") {
        fileType = "#icon-wenjianleixing-txt1";
      } else if (
        it.suffix == "png" ||
        it.suffix == "jpeg" ||
        it.suffix == "jpg" ||
        it.suffix == "bmp" ||
        it.suffix == "BMP" ||
        it.suffix == "gif"
      ) {
        fileType = "#icon-wenjianleixing-img1";
      } else if (it.suffix == "xls" || it.suffix == "xlsx") {
        fileType = "#icon-wenjianleixing-xls1";
      } else if (it.suffix == "doc" || it.suffix == "docx") {
        fileType = "#icon-wenjianleixing-docx1";
      } else if (it.suffix == "pdf") {
        fileType = "#icon-wenjianleixing-pdf1";
      } else if (it.suffix == "ppt" || it.suffix == "pptx") {
        fileType = "#icon-wenjianleixing-ppt1";
      } else if (it.suffix == "zip") {
        fileType = "#icon-wenjianleixing-zip1";
      } else if (it.suffix == "rar") {
        fileType = "#icon-wenjianleixing-rar1";
      } else {
        fileType = "#icon-wenjianleixing-qita1";
      }
      return {
        ...it,
        fileType,
      };
    });
    return arr;
  },
  // 处理文件格式
  shiftType(type) {
    // type 为空，默认为文件类型
    if (!type) {
      return 1;
    }
    // type是mime类型格式，需要判断的只有视频和图片
    let str = type.split("/")[0];
    if (str === "image" || type == "image") {
      return 2;
    } else if (str === "video" || type == "video") {
      return 3;
    } else {
      // 剩余类型全部默认为文件类型
      return 1;
    }
  },
  // 字典回显
  getDicLabel(list, value) {
    return ((list && list.find((item) => item.deptId == value)) || {}).deptName;
  },
  // 判断是否为对象，用于公共函数looseEqual
  isObject(obj) {
    return obj !== null && typeof obj === "object";
  },
  //判断两个对象是否相同（包含绝对相等和他们是否有相同的形状）
  /**
   * 时间整理方法
   * @param a :对象1
   * @param fmt :对象2
   * @returns {Boolean}返回布尔值，
   */
  looseEqual(a, b) {
    if (a === b) {
      //如果是绝对相等就直接返回true
      return true;
    }
    //如果不是绝对相等就哦按的他们是否有相同的形状
    var isObjectA = commontFn.isObject(a);
    var isObjectB = commontFn.isObject(b);
    if (isObjectA && isObjectB) {
      //两个均是对象
      try {
        var isArrayA = Array.isArray(a);
        var isArrayB = Array.isArray(b);
        if (isArrayA && isArrayB) {
          //如果都是数组
          if (a.length === b.length) {
            //如果长度相等
            return a.every(function (e, i) {
              //用every和递归来比对a数组和b数组的每个元素，并返回
              return looseEqual(e, b[i]);
            });
          }
          //长度都不等直接返回false
          return false;
        } else if (a instanceof Date && b instanceof Date) {
          //如果是Date 则直接getTime 比较
          return a.getTime() === b.getTime();
        } else if (!isArrayA && !isArrayB) {
          //对象的比较
          //拿到两个对象的key
          var keysA = Object.keys(a);
          var keysB = Object.keys(b);
          if (keysA.length === keysB.length) {
            //如果keys相等
            return keysA.every(function (key) {
              //用every和递归来比对a对象和b对象的每个元素值，并返回
              return looseEqual(a[key], b[key]);
            });
          }
          //长度都不等直接返回false
          return false;
        } else {
          return false;
        }
      } catch (e) {
        return false;
      }
    } else if (!isObjectA && !isObjectB) {
      //如果都不是对象则按String来处理
      return String(a) === String(b);
    } else {
      return false;
    }
  },
  // 单位换算
  formatSizeUnits(kb) {
    let units = ["KB", "MB", "GB", "TB", "PB"];
    let unitIndex = 0;

    while (kb >= 1024 && unitIndex < units.length - 1) {
      kb /= 1024;
      unitIndex++;
    }
    return `${kb.toFixed(2)} ${units[unitIndex]}`;
  },
  /**
   * 构造树型结构数据
   * @param {*} flatArray 数据源
   * @param {*} idField id字段 默认 'id'
   * @param {*} parentIdField 父节点字段 默认 'parentId'
   * @param {*} childrenField 孩子节点字段 默认 'children'
   */
  buildTree(
    flatArray,
    idField = "id",
    parentIdField = "parentId",
    childrenField = "children"
  ) {
    const tree = [];
    const nodeMap = {};
    // 首先将所有节点放入一个映射表中，以便快速查找
    flatArray.forEach((node) => {
      const newNode = {
        [idField]: node[idField],
        [parentIdField]: node[parentIdField],
        ...node, // 复制其他字段
      };
      nodeMap[newNode[idField]] = newNode;
    });

    // 构建树结构
    flatArray.forEach((node) => {
      const currentNode = nodeMap[node[idField]];
      if (node[parentIdField] === null) {
        // 如果是根节点，直接加入树中
        tree.push(currentNode);
      } else {
        // 找到父节点，并将当前节点添加到父节点的 children 数组中
        const parentNode = nodeMap[node[parentIdField]];
        if (parentNode) {
          const children = parentNode?.[childrenField] || [];
          children.push(currentNode);
          parentNode[childrenField] = children;
        }
      }
    });
    return tree;
  },
  // 扁平化树形数据
  flattenData(data) {
    if (!data || !data.length) return;
    let flattened = [];
    data.forEach((item) => {
      // 如果有子节点，则将子节点展开
      if (item.children && Array.isArray(item.children)) {
        item.children.forEach((child) => {
          // 只保留子节点的信息
          flattened.push({
            nickName: child.nickName,
            task: child.task,
          });
        });
      }
    });
    return flattened;
  },
};
export default commontFn;
